// ============================================
// 12 - Trait (特征)
// ============================================

/// Trait 定义共享的行为
/// 类似于其他语言中的接口 (interface)

// ==================== 定义 Trait ====================

/// 定义 trait
pub trait Summary {
    fn summarize(&self) -> String;
}

pub fn defining_traits() {
    println!("\n=== 定义 Trait ===");
    
    println!("trait 定义了类型必须提供的行为");
    println!("trait 可以包含方法签名");
}

// ==================== 实现 Trait ====================

/// 为类型实现 trait
pub struct NewsArticle {
    pub headline: String,
    pub location: String,
    pub author: String,
    pub content: String,
}

impl Summary for NewsArticle {
    fn summarize(&self) -> String {
        format!("{}, by {} ({})", self.headline, self.author, self.location)
    }
}

pub struct Tweet {
    pub username: String,
    pub content: String,
    pub reply: bool,
    pub retweet: bool,
}

impl Summary for Tweet {
    fn summarize(&self) -> String {
        format!("{}: {}", self.username, self.content)
    }
}

pub fn implementing_traits() {
    println!("\n=== 实现 Trait ===");
    
    let tweet = Tweet {
        username: String::from("horse_ebooks"),
        content: String::from("当然，就像你们可能已经知道的那样"),
        reply: false,
        retweet: false,
    };
    
    println!("1 条新推文: {}", tweet.summarize());
    
    let article = NewsArticle {
        headline: String::from("企鹅队赢得斯坦利杯冠军!"),
        location: String::from("匹兹堡, PA, USA"),
        author: String::from("Iceburgh"),
        content: String::from("企鹅队再次成为 NHL 最棒的球队"),
    };
    
    println!("新文章: {}", article.summarize());
}

// ==================== 默认实现 ====================

/// 带默认实现的 trait
pub trait SummaryWithDefault {
    fn summarize_author(&self) -> String;
    
    // 默认实现
    fn summarize_default(&self) -> String {
        format!("(阅读更多来自 {} ...)", self.summarize_author())
    }
}

impl SummaryWithDefault for Tweet {
    fn summarize_author(&self) -> String {
        format!("@{}", self.username)
    }
    // 使用默认的 summarize_default 实现
}

pub fn default_implementations() {
    println!("\n=== 默认实现 ===");
    
    let tweet = Tweet {
        username: String::from("horse_ebooks"),
        content: String::from("当然，就像你们可能已经知道的那样"),
        reply: false,
        retweet: false,
    };
    
    println!("默认摘要: {}", tweet.summarize_default());
}

// ==================== Trait 作为参数 ====================

/// trait 作为函数参数
pub fn notify(item: &impl Summary) {
    println!("突发新闻! {}", item.summarize());
}

pub fn trait_as_parameters() {
    println!("\n=== Trait 作为参数 ===");
    
    let article = NewsArticle {
        headline: String::from("企鹅队赢得斯坦利杯冠军!"),
        location: String::from("匹兹堡, PA, USA"),
        author: String::from("Iceburgh"),
        content: String::from("企鹅队再次成为 NHL 最棒的球队"),
    };
    
    notify(&article);
}

// ==================== Trait Bound 语法 ====================

/// trait bound 语法
pub fn notify_bound<T: Summary>(item: &T) {
    println!("突发新闻! {}", item.summarize());
}

/// 多个 trait bound
pub fn notify_multiple<T: Summary + std::fmt::Display>(item: &T) {
    println!("{}", item);
}

pub fn trait_bounds() {
    println!("\n=== Trait Bound ===");
    
    let article = NewsArticle {
        headline: String::from("企鹅队赢得!"),
        location: String::from("匹兹堡"),
        author: String::from("Iceburgh"),
        content: String::from("企鹅队最棒"),
    };
    
    notify_bound(&article);
}

// ==================== where 子句 ====================

/// 使用 where 子句清晰地指定 trait bound
pub fn some_function<T, U>(t: &T, u: &U) -> i32
where
    T: std::fmt::Display + Clone,
    U: Clone + std::fmt::Debug,
{
    println!("t: {}", t);
    println!("u: {:?}", u);
    42
}

pub fn where_clauses() {
    println!("\n=== where 子句 ===");
    
    let result = some_function(&"Hello", &vec![1, 2, 3]);
    println!("结果: {}", result);
}

// ==================== 返回 Trait ====================

/// 返回实现了 trait 的类型
pub fn returns_summarizable() -> impl Summary {
    Tweet {
        username: String::from("horse_ebooks"),
        content: String::from("当然，就像你们可能已经知道的那样"),
        reply: false,
        retweet: false,
    }
}

pub fn returning_traits() {
    println!("\n=== 返回 Trait ===");
    
    let tweet = returns_summarizable();
    println!("返回的 tweet: {}", tweet.summarize());
}

// ==================== 使用 Trait Bound 有条件地实现方法 ====================

/// 条件实现
struct Pair<T> {
    x: T,
    y: T,
}

impl<T> Pair<T> {
    fn new(x: T, y: T) -> Self {
        Pair { x, y }
    }
}

// 只为实现了 Display 和 PartialOrd 的类型实现 cmp_display
impl<T: std::fmt::Display + PartialOrd> Pair<T> {
    fn cmp_display(&self) {
        if self.x >= self.y {
            println!("最大的是 x = {}", self.x);
        } else {
            println!("最大的是 y = {}", self.y);
        }
    }
}

pub fn conditional_implementations() {
    println!("\n=== 条件实现 ===");
    
    let pair = Pair::new(10, 20);
    pair.cmp_display();
}

// ==================== 常见的标准库 Trait ====================

/// Display trait
use std::fmt;

struct Point {
    x: i32,
    y: i32,
}

impl fmt::Display for Point {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({}, {})", self.x, self.y)
    }
}

pub fn display_trait() {
    println!("\n=== Display Trait ===");
    
    let point = Point { x: 3, y: 4 };
    println!("点: {}", point);
}

/// Debug trait
#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}

pub fn debug_trait() {
    println!("\n=== Debug Trait ===");
    
    let rect = Rectangle {
        width: 30,
        height: 50,
    };
    
    println!("调试输出: {:?}", rect);
    println!("美化输出: {:#?}", rect);
}

/// Clone 和 Copy trait
#[derive(Clone, Copy, Debug)]
struct Pointy {
    x: i32,
    y: i32,
}

pub fn clone_and_copy() {
    println!("\n=== Clone 和 Copy ===");
    
    let p1 = Pointy { x: 1, y: 2 };
    let p2 = p1; // Copy
    let p3 = p1.clone(); // Clone
    
    println!("p1: {:?}, p2: {:?}, p3: {:?}", p1, p2, p3);
}

/// PartialEq 和 Eq trait
#[derive(PartialEq, Eq, Debug)]
struct Book {
    title: String,
    pages: u32,
}

pub fn equality_traits() {
    println!("\n=== PartialEq 和 Eq ===");
    
    let book1 = Book {
        title: String::from("Rust 编程"),
        pages: 500,
    };
    
    let book2 = Book {
        title: String::from("Rust 编程"),
        pages: 500,
    };
    
    println!("book1 == book2: {}", book1 == book2);
}

/// PartialOrd 和 Ord trait
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug)]
struct Student {
    name: String,
    grade: u32,
}

pub fn ordering_traits() {
    println!("\n=== PartialOrd 和 Ord ===");
    
    let student1 = Student {
        name: String::from("Alice"),
        grade: 90,
    };
    
    let student2 = Student {
        name: String::from("Bob"),
        grade: 85,
    };
    
    if student1 > student2 {
        println!("{:?} > {:?}", student1, student2);
    } else {
        println!("{:?} <= {:?}", student1, student2);
    }
}

// ==================== Iterator Trait ====================

/// 实现 Iterator trait
struct Counter {
    count: u32,
}

impl Counter {
    fn new() -> Counter {
        Counter { count: 0 }
    }
}

impl Iterator for Counter {
    type Item = u32;
    
    fn next(&mut self) -> Option<Self::Item> {
        if self.count < 5 {
            self.count += 1;
            Some(self.count)
        } else {
            None
        }
    }
}

pub fn iterator_trait() {
    println!("\n=== Iterator Trait ===");
    
    let counter = Counter::new();
    
    for num in counter {
        println!("计数: {}", num);
    }
}

// ==================== From 和 Into Trait ====================

/// From trait
struct MyNumber {
    value: i32,
}

impl From<i32> for MyNumber {
    fn from(num: i32) -> Self {
        MyNumber { value: num }
    }
}

pub fn from_trait() {
    println!("\n=== From Trait ===");
    
    let num = MyNumber::from(42);
    println!("MyNumber: {}", num.value);
    
    // Into trait 自动实现
    let num: MyNumber = 100.into();
    println!("使用 into: {}", num.value);
}

// ==================== Drop Trait ====================

/// Drop trait 自定义清理代码
struct CustomSmartPointer {
    data: String,
}

impl Drop for CustomSmartPointer {
    fn drop(&mut self) {
        println!("释放 CustomSmartPointer: {}", self.data);
    }
}

pub fn drop_trait() {
    println!("\n=== Drop Trait ===");
    
    {
        let _c = CustomSmartPointer {
            data: String::from("我的数据"),
        };
        println!("创建了 CustomSmartPointer");
    } // _c 在这里被 drop
    
    println!("CustomSmartPointer 已被释放");
}

// ==================== Deref Trait ====================

/// Deref trait
use std::ops::Deref;

struct MyBox<T>(T);

impl<T> MyBox<T> {
    fn new(x: T) -> MyBox<T> {
        MyBox(x)
    }
}

impl<T> Deref for MyBox<T> {
    type Target = T;
    
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

pub fn deref_trait() {
    println!("\n=== Deref Trait ===");
    
    let x = 5;
    let y = MyBox::new(x);
    
    assert_eq!(5, x);
    assert_eq!(5, *y); // 解引用
    
    println!("解引用成功");
}

// ==================== Trait 对象 ====================

/// trait 对象实现动态分发
pub trait Draw {
    fn draw(&self);
}

pub struct Button {
    pub width: u32,
    pub height: u32,
    pub label: String,
}

impl Draw for Button {
    fn draw(&self) {
        println!("绘制按钮: {}", self.label);
    }
}

pub struct SelectBox {
    pub width: u32,
    pub height: u32,
    pub options: Vec<String>,
}

impl Draw for SelectBox {
    fn draw(&self) {
        println!("绘制选择框，选项: {:?}", self.options);
    }
}

pub struct Screen {
    pub components: Vec<Box<dyn Draw>>,
}

impl Screen {
    pub fn run(&self) {
        for component in self.components.iter() {
            component.draw();
        }
    }
}

pub fn trait_objects() {
    println!("\n=== Trait 对象 ===");
    
    let screen = Screen {
        components: vec![
            Box::new(Button {
                width: 50,
                height: 10,
                label: String::from("确定"),
            }),
            Box::new(SelectBox {
                width: 75,
                height: 10,
                options: vec![
                    String::from("是"),
                    String::from("否"),
                    String::from("可能"),
                ],
            }),
        ],
    };
    
    screen.run();
}

// ==================== 关联类型 ====================

/// 关联类型
pub trait Iterator2 {
    type Item; // 关联类型
    
    fn next(&mut self) -> Option<Self::Item>;
}

pub fn associated_types() {
    println!("\n=== 关联类型 ===");
    
    println!("关联类型与泛型的区别:");
    println!("- 关联类型: 每个实现只能有一个具体类型");
    println!("- 泛型: 可以为同一个类型实现多次");
}

// ==================== 运算符重载 ====================

/// 使用 trait 重载运算符
use std::ops::Add;

#[derive(Debug, Copy, Clone, PartialEq)]
struct Pointz {
    x: i32,
    y: i32,
}

impl Add for Pointz {
    type Output = Pointz;
    
    fn add(self, other: Pointz) -> Pointz {
        Pointz {
            x: self.x + other.x,
            y: self.y + other.y,
        }
    }
}

pub fn operator_overloading() {
    println!("\n=== 运算符重载 ===");
    
    let p1 = Pointz { x: 1, y: 2 };
    let p2 = Pointz { x: 3, y: 4 };
    let p3 = p1 + p2;
    
    println!("{:?} + {:?} = {:?}", p1, p2, p3);
}

// ==================== 完全限定语法 ====================

/// 完全限定语法调用方法
trait Pilot {
    fn fly(&self);
}

trait Wizard {
    fn fly(&self);
}

struct Human;

impl Pilot for Human {
    fn fly(&self) {
        println!("这是机长广播");
    }
}

impl Wizard for Human {
    fn fly(&self) {
        println!("起飞!");
    }
}

impl Human {
    fn fly(&self) {
        println!("*疯狂挥舞手臂*");
    }
}

pub fn fully_qualified_syntax() {
    println!("\n=== 完全限定语法 ===");
    
    let person = Human;
    
    person.fly(); // 调用 Human 的方法
    Pilot::fly(&person); // 调用 Pilot trait 的方法
    Wizard::fly(&person); // 调用 Wizard trait 的方法
}

// ==================== Trait 最佳实践 ====================

/// trait 使用最佳实践
pub fn best_practices() {
    println!("\n=== Trait 最佳实践 ===");
    
    println!("1. 为自定义类型实现标准库 trait");
    println!("2. 使用 trait bound 限制泛型");
    println!("3. 提供有用的默认实现");
    println!("4. 考虑使用 trait 对象实现动态分发");
    println!("5. 使用关联类型简化 trait 定义");
    println!("6. 为常见操作实现标准运算符 trait");
    println!("7. 使用派生宏减少样板代码");
}

/// 主函数 - 演示所有功能
#[allow(dead_code)]
pub fn main() {
    println!("╔════════════════════════════════════════╗");
    println!("║   Rust Trait 教程                      ║");
    println!("╚════════════════════════════════════════╝");
    
    defining_traits();
    implementing_traits();
    default_implementations();
    trait_as_parameters();
    trait_bounds();
    where_clauses();
    returning_traits();
    conditional_implementations();
    display_trait();
    debug_trait();
    clone_and_copy();
    equality_traits();
    ordering_traits();
    iterator_trait();
    from_trait();
    drop_trait();
    deref_trait();
    trait_objects();
    associated_types();
    operator_overloading();
    fully_qualified_syntax();
    best_practices();
    
    println!("\n✅ Trait 教程完成！");
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_summary() {
        let tweet = Tweet {
            username: String::from("test"),
            content: String::from("hello"),
            reply: false,
            retweet: false,
        };
        assert!(tweet.summarize().contains("test"));
    }
    
    #[test]
    fn test_point_add() {
        let p1 = Pointz { x: 1, y: 2 };
        let p2 = Pointz { x: 3, y: 4 };
        let p3 = p1 + p2;
        assert_eq!(p3, Pointz { x: 4, y: 6 });
    }
}

